///////////////////////////////////////////////////////////////////////////////
//	FILENAME:	eTAudio.m
//	SUMMARY:	Implementation of Audio annotations to eText documents
//	SUPERCLASS:	eTAudio:eTImage:Object
//	INTERFACE:	None
//	PROTOCOLS:	<DocNotification, Annotation, Tool, ASCIISupport, HTMDSupport,
//				LaTeXSupport, eTAudioNotification, InspectableTarget>
//	AUTHOR:		Rohit Khare
//	COPYRIGHT:	(c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
//	IMPLEMENTATION COMMENTS
//		There is a delicate ballet of timings, displays, and messages betwixt
//	self, inspector panel, sound view, sound meter, sound, and delegate
//	messages all around.
///////////////////////////////////////////////////////////////////////////////
//	HISTORY
//	10/30/94:	Modified to support <InspectableTarget>
//	07/24/94:	Rewritten for PR1 release/eTImage
//  07/07/94:	Rewritten as a subclass of ImageAnnotation
//	06/18/94:	HTMDSupport. RK & TRZ.
//	01/24/94:	Created. Derived largely from Version3's temporary Hypertext
//				'93 hack. Renamed as eTAudio and eTAudioUI.
///////////////////////////////////////////////////////////////////////////////

#import "eTAudio.h"
#define _eTAudioVERSION	10

@implementation eTAudio
//	id	etAudioComponent;
/////////////////////////
- sound {return [etAudioComponent theSound];}
- (BOOL)isAudioMutable{return [etAudioComponent isMutable];}
- (BOOL)isAudioLinked{return [etAudioComponent isLinked];}
- (const char*)audioName {return [etAudioComponent componentName];}
- setAudioName:(const char*) newName
	{return [etAudioComponent setComponentName:NXUniqueString(newName)];}
- setAudioDelegate:(id <eTAudioNotification>) newDelegate
	{audioDelegate = newDelegate; return self;}
- audioDelegate	{return audioDelegate;}
/////////////////////////
- audioStarted 
	{[audioDelegate audioStarted]; return [self setState:YES];}
- audioPaused 				// it would be cool to "dim" the speaking icon...
	{[audioDelegate audioPaused]; return self;}
- audioResumed 				// and this would be the inverse brighten...
	{[audioDelegate audioResumed]; return self;}
- audioEnded 
	{[audioDelegate audioEnded]; return [self setState:NO];}
/////////////////////////
+ toolAwake:theApp
{
	[theApp   registerAnnotation: [eTAudio class] 
							name: "eTAudio"
					RTFDirective: "eTAudio"
					   menuLabel: "Insert Audio..."
						 menuKey: 'A'
						menuIcon: (NXImage *) nil];
	[theApp registerType:NXSoundPboardType for:[eTAudio class]];
	[theApp registerType:NXCreateFilenamePboardType("snd") for:[eTAudio class]];
	[theApp registerType:NXCreateFilenamePboardType("au") for:[eTAudio class]];
	[theApp registerType:NXCreateFileContentsPboardType("snd") for:[eTAudio class]];
	[theApp registerType:NXCreateFileContentsPboardType("au") for:[eTAudio class]];
	return self;
}

- init
{
	[super init];
	
	[self setImageComponent:
		[eTImageComponent newImageNamed:"eTAudioComponentIcon"]];	
	[self setAltImageComponent:
		[eTImageComponent newImageNamed:"eTAudioComponentIconH"]];
	[self setUsesButtonStyle:NO];
	[self setDraggable:YES];
	etAudioComponent=nil;
	return self;
}

- free 
{
	etAudioComponent = [etAudioComponent free];
	return self = [super free];
}
//////////////////////////////
- initFromPboard:thePB inDoc:theDoc linked:(BOOL) linked
{
	[self init];
	// we prevent super from executing initFromPboard, so we have to:
	etDoc = theDoc;
	theText = [[etDoc docUI] eTextObj]; // consistency checking
	[etDoc registerNotification:self];
	
	if (!thePB) {
		etAudioComponent = [[eTAudioComponent alloc] initInDoc:theDoc linked:NO];
		return self;
	}
	etAudioComponent=[[eTAudioComponent alloc] initInDoc:theDoc linked:linked];
	[etAudioComponent readComponentFromPboard:thePB];
	return self;
}
#define eTAUDIO "eTAudioComponentIcon"
#define eTAUDIO_GIF eTAUDIO".gif"
- writeComponentToPath:(NXAtom)path inFormat:(int) theFormat
{
	const char *name;
	
	if(!etDoc)	NXLogError("etDoc is nil at %s %u",__FILE__,__LINE__);
	name = [[imageComponent theImage] name];
	if ((theFormat == HTMD_FMT) && 
		name && !strcmp(name,eTAUDIO)) {
		char cmd[2*MAXPATHLEN];

		sprintf(cmd,"%s/"eTAUDIO_GIF, [[NXBundle mainBundle] directory]);
		if (!access(cmd, F_OK|R_OK)) {
		 	sprintf(cmd,"cp -rp \"%s/"eTAUDIO_GIF"\" \"%s/"eTAUDIO_GIF"\"", [[NXBundle mainBundle] directory], path);
		 	system(cmd);
			[etDoc registerComponent:eTAUDIO_GIF];
		} else {
			[super writeComponentToPath:path inFormat:theFormat];
		}
	} else 
		[super writeComponentToPath:path inFormat:theFormat];
	[etAudioComponent writeComponentToPath:path inFormat:theFormat];
	return self;
}

- addToPboard:pboard
{
	[etAudioComponent addToPboard:pboard];
	return self;
}
- readRichText:(NXStream *)stream forView:view 
{
	int i;

	NXScanf(stream, "%d ", &i);
	if (i != _eTAudioVERSION) {
		// bad version block.
		NXLogError("eTAudio found unparseable version %d at position %d",
					i, NXTell(stream));
		return nil;
	}
	[super readRichText:stream forView:view];
	NXGetc(stream); // separating space
	etAudioComponent = [[[eTAudioComponent alloc] initInDoc:etDoc linked:NO] readRichText:stream forView:view];
	return self;
}

- writeRichText:(NXStream *)stream forView:view
{	
	NXPrintf(stream, "%d ", _eTAudioVERSION); 
	[super writeRichText:stream forView:view];
	NXPutc(stream, ' ');	// separate the two visually
	[etAudioComponent writeRichText:stream forView:view];
	return self;
}

- writeASCIIRef:(NXStream *)stream forView:view
{
	NXPrintf(stream, "The audio annotation %y (last known address:%s)\n\t", [etAudioComponent componentName], [etAudioComponent currentPath]);
	[super writeASCIIRef:stream forView:view];
	return self;
}

- writeLaTeX:(NXStream*)stream forView:view
{	
	[super writeLaTeX:stream forView:view];
	[etAudioComponent writeLaTeX:stream forView:view];
	return self;
}

- writeHTML:(NXStream *)stream forView:view
{ 		
	[etAudioComponent writeHTML:stream forView:view andClose:NO];
	[super writeHTML:stream forView:view];
	NXPrintf(stream,"</A>");
	return self;
}

//////////////////////////////
// the "delegate" calls below explicitly assume that inspect is called
// _before_ click or double-click. (this is indeed done by eTImage).
// (it is safe though -- nothing will happen)
- click:(NXEvent*)e 
	{return [[eTAudioUI new] click:self];}
- doubleClick:(NXEvent*)e 
	{return [[eTAudioUI new] doubleClick:self];}
- inspect:(NXEvent *) e
	{return [[NXApp inspector] inspect:self];}
- (id <Inspectable>) inspectableDelegate {
	return [[eTAudioUI new] setAnnotation:self]; }

- drag: (Pasteboard *)draggingPboard image:(NXImage **)proxyImage
{
	if (! etAudioComponent) {
		*proxyImage = nil;
		return nil;
	}
	[etAudioComponent writeComponentToPboard:draggingPboard];
	*proxyImage = [etAudioComponent icon];
	return self;
}

//////////////////////////////
- setImageComponent:newImageComponent
{
	const char *name;
	
	name = [[newImageComponent theImage] name];
	if (name && !strcmp(name,"eTAudioComponentIcon"))
		usesButtonStyle = NO;
	else
		usesButtonStyle = YES;
	return [super setImageComponent:newImageComponent];
}

@end